﻿using AForge.Video;
using AForge.Video.DirectShow;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Media;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsInput;
using ZXing;

namespace QRCodeScanning
{
    public partial class MainForm : Form
    {
        private FilterInfoCollection videoDevices;
        private VideoCaptureDevice videoSource;
        private readonly InputSimulator inputSimulator = new InputSimulator();
        private bool isScanning = false; //控制是否可以扫描

        private Timer scanTimer;
        private bool isScanReady = true; // 控制是否可以进行下一次扫描

        public MainForm()
        {
            InitializeComponent();
            InitializeCameraList();
        }

        private void InitializeCameraList()
        {
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

            foreach (FilterInfo device in videoDevices)
            {
                cboCamera.Items.Add(device.Name);
            }

            if (cboCamera.Items.Count > 0)
            {
                cboCamera.SelectedIndex = 0;
            }
            else
            {
                MessageBox.Show("未检测到摄像头设备，无法使用相关功能！确认后台退出。","提示",MessageBoxButtons.OK,MessageBoxIcon.Asterisk);
                this.Close();
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            // 如果已经在运行，则先停止
            if (videoSource != null && videoSource.IsRunning)
            {
                MessageBox.Show("已开始扫描请不要重复点击开始扫描！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                return;
            }

            videoSource = new VideoCaptureDevice(videoDevices[cboCamera.SelectedIndex].MonikerString);
            videoSource.NewFrame += VideoSource_NewFrame;
            videoSource.Start();

            // 初始化并启动扫描定时器
            if (scanTimer == null)
            {
                scanTimer = new Timer();
                scanTimer.Interval = (int)numTime.Value; 
                scanTimer.Tick += (s, args) => { isScanReady = true; };
            }
            else
            {
                // 如果定时器已存在，更新间隔并重新启动
                scanTimer.Interval = (int)numTime.Value;
                scanTimer.Stop(); 
            }

            scanTimer.Start();

            isScanning = true;
            isScanReady = true; // 立即允许第一次扫描
            lblStatus.Text = "扫描中...";
        }
        
        private void btnStop_Click(object sender, EventArgs e)
        {
            try
            {
                if (videoSource != null && videoSource.IsRunning)
                {
                    videoSource.NewFrame -= VideoSource_NewFrame;
                    videoSource.SignalToStop();
                    
                    int timeout = 2000; 
                    int elapsed = 0;
                    int sleepInterval = 100;
            
                    while (videoSource.IsRunning && elapsed < timeout)
                    {
                        Application.DoEvents(); 
                        System.Threading.Thread.Sleep(sleepInterval);
                        elapsed += sleepInterval;
                    }
                    
                    if (videoSource.IsRunning)
                    {
                        Debug.WriteLine("视频源停止超时");
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("停止视频源时出错: " + ex.Message);
            }
            finally
            {
                // 停止扫描定时器
                if (scanTimer != null && scanTimer.Enabled)
                {
                    scanTimer.Stop();
                }

                // 更新状态
                isScanning = false;
                lblStatus.Text = "已停止";
        
                // 强制释放视频源资源
                videoSource = null;
            }
        }

        // 在 MainForm 类中添加一个新的 PictureBox 控件引用
// 假设在窗体设计器中添加了一个名为 pbVideoPreview 的 PictureBox 控件

        private void VideoSource_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {
            // 只有当允许扫描且处于扫描状态时才处理
            if (!isScanning || !isScanReady) return;

            try
            {
                using (var bitmap = (Bitmap)eventArgs.Frame.Clone())
                {
                    if (bitmap == null || bitmap.Width == 0 || bitmap.Height == 0) return;

   

                    var barcodeReader = new BarcodeReader
                    {
                        AutoRotate = true,
                        Options = new ZXing.Common.DecodingOptions
                        {
                            TryHarder = true,
                            PossibleFormats = new List<BarcodeFormat>
                            {
                                BarcodeFormat.QR_CODE,
                                BarcodeFormat.CODE_128,
                                BarcodeFormat.CODE_39,
                                BarcodeFormat.CODE_93,
                                BarcodeFormat.EAN_13,
                                BarcodeFormat.EAN_8,
                                BarcodeFormat.UPC_A,
                                BarcodeFormat.UPC_E,
                                BarcodeFormat.ITF
                            }
                        }
                    };

                    var luminanceSource = new BitmapLuminanceSource(bitmap);
                    var result = barcodeReader.Decode(luminanceSource);

                    // 获取当前聚焦窗口信息并显示
                    this.Invoke((MethodInvoker)delegate
                    {
                        var windowHandle = GetForegroundWindow();
                        if (windowHandle != IntPtr.Zero)
                        {
                            var windowTitle = GetWindowText(windowHandle);
                            lblFocusedWindow.Text = "当前聚焦: " + windowTitle;
                        }
                        else
                        {
                            lblFocusedWindow.Text = "暂无聚焦窗口，无法正常输出";
                        }
                    });

                    if (result != null && !string.IsNullOrEmpty(result.Text))
                    {
                        // 扫描到结果后，设置下次扫描准备状态为false
                        isScanReady = false;
                        
                        // 抓拍摄像头画面 渲染到ui上
                        this.Invoke((MethodInvoker)delegate
                        {
                            //自适应图片大小
                            pictureBox_CodePicture.SizeMode = PictureBoxSizeMode.Zoom;
                            
                            if (pictureBox_CodePicture.Image != null)
                            {
                                pictureBox_CodePicture.Image.Dispose();
                            }

                            pictureBox_CodePicture.Image = (Bitmap)bitmap.Clone();
                        });
                        
                        this.Invoke((MethodInvoker)delegate
                        {
                            try
                            {
                                var windowHandle = GetForegroundWindow();
                                if (windowHandle != IntPtr.Zero)
                                {
                                    var windowTitle = GetWindowText(windowHandle);

                                    inputSimulator.Keyboard.TextEntry(result.Text);

                                    if (chkAutoEnter.Checked)
                                    {
                                        inputSimulator.Keyboard.KeyPress(WindowsInput.Native.VirtualKeyCode.RETURN);
                                    }

                                    lblLastCode.Text = "上次扫描: " + result.Text + "\r\n时间：" + DateTime.Now.ToString();
                                    SystemSounds.Beep.Play();
                                }
                            }
                            catch (Exception ex)
                            {
                                Debug.WriteLine("输入模拟错误: " + ex.Message);
                            }
                        });

                        if (chkPauseAfterScan.Checked)
                        {
                            isScanning = false;
                            this.Invoke((MethodInvoker)delegate { lblStatus.Text = "已暂停 (扫描到内容)"; });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("解码错误: " + ex.Message);
            }
        }


        // 添加Windows API声明用于检查活动窗口
        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();
        
        [DllImport("user32.dll")]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

        private string GetWindowText(IntPtr hWnd)
        {
            const int nChars = 256;
            StringBuilder sb = new StringBuilder(nChars);
            int length = GetWindowText(hWnd, sb, nChars);
    
            // 检查返回的长度是否有效
            if (length > 0 && length <= nChars)
            {
                // 确保不会越界
                int actualLength = Math.Min(length, sb.Length);
                if (actualLength > 0)
                {
                    return sb.ToString(0, actualLength);
                }
            }

            // 如果没有获取到窗口标题，则返回空字符串
            return string.Empty;
        }

        private void btnResume_Click(object sender, EventArgs e)
        {
            isScanning = true;
            isScanReady = true; // 恢复时重置扫描准备状态
            lblStatus.Text = "扫描中...";
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 停止并释放定时器
            if (scanTimer != null)
            {
                scanTimer.Stop();
                scanTimer.Dispose();
                scanTimer = null;
            }
    
            if (videoSource != null)
            {
                // 先移除事件处理程序
                videoSource.NewFrame -= VideoSource_NewFrame;
        
                // 如果正在运行则停止
                if (videoSource.IsRunning)
                {
                    videoSource.SignalToStop();
                    
                    int timeout = 3000; 
                    int elapsed = 0;
                    int sleepInterval = 100;
            
                    while (videoSource.IsRunning && elapsed < timeout)
                    {
                        System.Threading.Thread.Sleep(sleepInterval);
                        elapsed += sleepInterval;
                    }
                }
                // 强制释放资源
                videoSource = null;
            }
        }


        private void btnFormTop_Click(object sender, EventArgs e)
        {
            // 切换窗口置顶状态
            if (this.TopMost)
            {
                this.TopMost = false;
                if (sender is Button button)
                {
                    button.Text = "窗口置顶";
                }
            }
            else
            {
                // 设置置顶
                this.TopMost = true;
                if (sender is Button button)
                {
                    button.Text = "取消置顶";
                }
            }
        }
    }
}